// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose:  Utilities to assist Tablet PC operation.
//   $Id$


#include "stdafx.h"
#include "TabletPCUtil.h"
#include <peninputpanel_i.c>

#ifndef SM_TABLETPC
#define SM_TABLETPC 86
#endif

static HANDLE sg_hPIPFactoryMutex = 0;
static CComPtr<IClassFactory> sg_pPIPFactory;

static HANDLE sg_hTIPFactoryMutex = 0;
static CComPtr<IClassFactory> sg_pTIPFactory;
static const CComBSTR scg_sTIPProgId = L"TabletTip.UIHost";
static CLSID sg_clsidTIP = CLSID_NULL;
static CComBSTR sg_sMethodShow = L"ShowWnd";

static CComVariant sg_vTrue = VARIANT_TRUE;
static CComVariant sg_vFalse = VARIANT_FALSE;

bool xport::RunningOnTabletPC(void)
{
	return GetSystemMetrics(SM_TABLETPC) != 0;
}

void xport::TabletPCClearUp(void)
{
	WaitForSingleObject(sg_hPIPFactoryMutex, INFINITE);
	if(sg_pPIPFactory)
		sg_pPIPFactory.Release();
	ReleaseMutex(sg_hPIPFactoryMutex);

	WaitForSingleObject(sg_hTIPFactoryMutex, INFINITE);
	if(sg_pTIPFactory)
		sg_pTIPFactory.Release();
	ReleaseMutex(sg_hTIPFactoryMutex);
}

void xport::CreatePIP(CComPtr<IPenInputPanel> &pPIP)
{
	if(!pPIP && CreatePIPFactory()) {
		WaitForSingleObject(sg_hPIPFactoryMutex, INFINITE);
		sg_pPIPFactory->CreateInstance(0, IID_IPenInputPanel, reinterpret_cast<void **>(&pPIP));
		ReleaseMutex(sg_hPIPFactoryMutex);
	}
}

void xport::InitialisePIP(IPenInputPanel *pPIP, HWND hEditWindow)
{
	if(pPIP) {
		pPIP->put_AttachedEditWindow(reinterpret_cast<LONG_PTR>(hEditWindow));
		pPIP->put_AutoShow(VARIANT_FALSE);
		pPIP->put_Visible(VARIANT_FALSE);
	}
}

bool xport::CreatePIPFactory(void)
{
	if(sg_hPIPFactoryMutex == 0)
		sg_hPIPFactoryMutex = CreateMutex(0, FALSE, _T("XPORT_TabletPC_PIPFactory_Mutex"));

	if(sg_hPIPFactoryMutex != 0) {
		WaitForSingleObject(sg_hPIPFactoryMutex, INFINITE);
		if(!sg_pPIPFactory)
			::CoGetClassObject(CLSID_PenInputPanel, CLSCTX_ALL, 0, IID_IClassFactory, reinterpret_cast<void **>(&sg_pPIPFactory));
		ReleaseMutex(sg_hPIPFactoryMutex);
	}

	return sg_pPIPFactory.p != 0;
}

bool xport::CreateTIP(CComPtr<IDispatch> &pTIP)
{
	if(!pTIP && CreateTIPFactory()) {
		WaitForSingleObject(sg_hTIPFactoryMutex, INFINITE);
		sg_pTIPFactory->CreateInstance(0, IID_IDispatch, reinterpret_cast<void **>(&pTIP));
		ReleaseMutex(sg_hTIPFactoryMutex);
	}

	return pTIP.p != 0;
}

void xport::ShowTIP(CComPtr<IDispatch> &pTIP)
{
	if(CreateTIP(pTIP)) {
		DISPID dispid = -1;
		if(SUCCEEDED(pTIP->GetIDsOfNames(IID_NULL, &sg_sMethodShow, 1, LOCALE_SYSTEM_DEFAULT, &dispid))) {
			DISPPARAMS dp = { &sg_vTrue, 0, 1, 0 };
			pTIP->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dp, 0, 0, 0);
		}
	}
}

void xport::HideTIP(CComPtr<IDispatch> &pTIP)
{
	if(CreateTIP(pTIP)) {
		DISPID dispid = -1;
		if(SUCCEEDED(pTIP->GetIDsOfNames(IID_NULL, &sg_sMethodShow, 1, LOCALE_SYSTEM_DEFAULT, &dispid))) {
			DISPPARAMS dp = { &sg_vFalse, 0, 1, 0 };
			pTIP->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dp, 0, 0, 0);
		}
	}
}

bool xport::CreateTIPFactory(void)
{
	if(sg_hTIPFactoryMutex == 0)
		sg_hTIPFactoryMutex = CreateMutex(0, FALSE, _T("XPORT_TabletPC_TIPFactory_Mutex"));

	if(IsEqualCLSID(CLSID_NULL, sg_clsidTIP) == TRUE)
		CLSIDFromProgID(scg_sTIPProgId, &sg_clsidTIP);

	if(sg_hTIPFactoryMutex != 0 && IsEqualCLSID(CLSID_NULL, sg_clsidTIP) == FALSE) {
		WaitForSingleObject(sg_hTIPFactoryMutex, INFINITE);
		if(!sg_pTIPFactory)
			::CoGetClassObject(sg_clsidTIP, CLSCTX_ALL, 0, IID_IClassFactory, reinterpret_cast<void **>(&sg_pTIPFactory));
		ReleaseMutex(sg_hTIPFactoryMutex);
	}

	return sg_pTIPFactory.p != 0;
}
